home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DTP / DTP_TEX / 3238.ZIP / DVIEPS2.ZIP / DVIEPS.C < prev    next >
Text File  |  1988-11-01  |  22KB  |  711 lines

  1. /*=======================================================================
  2. *    Program : DVIEPS.C
  3. *    Purpose : TeX device driver
  4. *       Date : Oct 1988
  5. *========================================================================
  6. *   Compiler : Microsoft V5.1 C Compiler
  7. *     Linker : Microsoft V3.61 Linker
  8. * Enviroment : MS-DOS 3.21
  9. *========================================================================
  10. * Edit History
  11. *
  12. *   /  /   -gbm- 
  13. *
  14. *======================================================================*/
  15.  
  16. #include "dvidefs.h"
  17.  
  18. #define extern
  19. #include "dvivars.h"
  20. #undef extern
  21.  
  22.  
  23. /***********************************************************************
  24. Magnification table for 144dpi, 200dpi, and 300dpi devices, computed
  25. to 20 figures and sorted by magnitude.
  26.  
  27.     Column 1         Column 2         Column 3
  28. 0.72*sqrt(1.2)**i  sqrt(1.2)**I  1.5*sqrt(1.2)**I    (I = -16,16)
  29.  
  30. ***********************************************************************/
  31.  
  32. double mag_table[] =
  33.    {
  34.    0.16744898601451165028, 0.18343117374303022733, 0.20093878321741398034,
  35.    0.22011740849163627280, 0.23256803936137783874, 0.24112653986089677641,
  36.    0.25476552262595201888, 0.26414089018996352736, 0.27908164723365340649,
  37.    0.28935184783307613169, 0.30571862715114242265, 0.31696906822795623283,
  38.    0.33489797668038408779, 0.34722221739969135802, 0.34885205904206675812,
  39.    0.36686235258137090718, 0.38036288187354747940, 0.38214828393892802832,
  40.    0.40187757201646090535, 0.41666666087962962963, 0.41862247085048010974,
  41.    0.44023482309764508862, 0.45643545824825697527, 0.45857794072671363398,
  42.    0.48225308641975308642, 0.49999999305555555556, 0.50234696502057613169,
  43.    0.52828178771717410634, 0.54772254989790837033, 0.55029352887205636077,
  44.    0.57870370370370370370, 0.59999999166666666667, 0.60281635802469135802,
  45.    0.63393814526060892761, 0.65726705987749004440, 0.66035223464646763293,
  46.    0.69444444444444444444, 0.71999999000000000000, 0.72337962962962962963,
  47.    0.76072577431273071313, 0.78872047185298805327, 0.79242268157576115952,
  48.    0.83333333333333333333, 0.86399998800000000000, 0.86805555555555555556,
  49.    0.91287092917527685576, 0.94646456622358566393, 0.95090721789091339142,
  50.    1.00000000000000000000, 1.03679998560000000000, 1.04166666666666666670,
  51.    1.09544511501033222690, 1.13575747946830279670, 1.14108866146909606970,
  52.    1.20000000000000000000, 1.24415998272000000000, 1.25000000000000000000,
  53.    1.31453413801239867230, 1.36290897536196335610, 1.36930639376291528360,
  54.    1.44000000000000000000, 1.49299197926400000000, 1.50000000000000000000,
  55.    1.57744096561487840680, 1.63549077043435602730, 1.64316767251549834040,
  56.    1.72800000000000000000, 1.79159037511680000000, 1.80000000000000000000,
  57.    1.89292915873785408810, 1.96258892452122723270, 1.97180120701859800840,
  58.    2.07360000000000000000, 2.14990845014016000000, 2.16000000000000000000,
  59.    2.27151499048542490570, 2.35510670942547267930, 2.36616144842231761010,
  60.    2.48832000000000000000, 2.57989014016819200000, 2.59200000000000000000,
  61.    2.72581798858250988690, 2.82612805131056721510, 2.83939373810678113220,
  62.    2.98598400000000000000, 3.09586816820183040000, 3.11040000000000000000,
  63.    3.27098158629901186430, 3.40727248572813735860, 3.58318080000000000000,
  64.    3.73248000000000000000, 3.92517790355881423710, 4.08872698287376483030,
  65.    4.29981696000000000000, 4.47897600000000000000, 4.90647237944851779640,
  66.    5.37477120000000000000, 5.88776685533822135560, 6.44972544000000000000
  67.    };
  68.  
  69.  
  70.  
  71. int main(int argc, char **argv)
  72.    {
  73.    register int k;        /* loop index */
  74.    register int file_args;    /* count of file arguments */
  75.  
  76.    (void)strcpy(g_progname, argv[0]); /* save program name */
  77.  
  78.    (void)initglob();        /* do this before argc check! */
  79.  
  80.    if (argc < 2)
  81.       {
  82.       (void)usage(stderr);
  83.       (void)exit(1);
  84.       }
  85.  
  86.    for (k = 1; k < argc; ++k)
  87.       {
  88.       if (*argv[k] == '-')    /* -switch */
  89.          (void)option(argv[k]);
  90.       }
  91.  
  92.    if (!quiet)
  93.       {
  94.       (void)fprintf(stderr,"[TeX82 DVI Translator Version %s]",VERSION_NO);
  95.       NEWLINE(stderr);
  96.       (void)fprintf(stderr,"[%s]",DEVICE_ID);
  97.       NEWLINE(stderr);
  98.       }
  99.  
  100.    if (npage == 0)        /* no page ranges given, make a large one */
  101.       {
  102.       page_begin[0] = 1;
  103.       page_end[0] = 32767;    /* arbitrary large integer */
  104.       page_step[0] = 1;
  105.       npage = 1;
  106.       }
  107.    else /* need font defs from postamble if only some pages to be output */
  108.       preload = TRUE;
  109.  
  110.    file_args = 0;
  111.    for (k = 1; k < argc; ++k)
  112.       {
  113.       if (*argv[k] != '-')     /* must be file argument */
  114.          {
  115.          file_args++;
  116.          (void)dvifile(argc,argv,argv[k]);
  117.          }
  118.       }
  119.  
  120.    (void)alldone();        /* this will never return */
  121.    return (0);            /* never executed; avoid compiler warnings */
  122.    }
  123.  
  124. /*******************************************************************
  125.     This routine  is called  on both  success and  failure to  terminate
  126.     execution.  All open files (except stdin, stdout, stderr) are closed
  127.     before calling EXIT() to quit.
  128.     *******************************************************************/
  129.  
  130.  
  131. void abortrun(code)
  132. int code;
  133.  
  134.    {
  135.    unsigned int k;
  136.    char *tcp;
  137.    char fname[100];
  138.  
  139.    for (k = 0; k < (unsigned int)nopen; ++k)
  140.       if (font_files[k].font_id != (FILE*)NULL)
  141.          (void)fclose(font_files[k].font_id);
  142.  
  143.    if (dvifp != (FILE*)NULL)
  144.       (void)fclose(dvifp);
  145.    if (plotfp != (FILE*)NULL)
  146.       (void)fclose(plotfp);
  147.    if (g_dolog && (g_logfp != (FILE *)NULL))
  148.       (void)fclose(g_logfp);
  149.    close(bmap_file);
  150.    if ((tcp = getenv("EPSBMAP")) == (char *)NULL)
  151.       strcpy(fname, "BMAP.TMP");
  152.    else
  153.       strcpy(fname, tcp);
  154.    unlink(fname);
  155.    (void)exit(code);
  156.    }
  157.  
  158.  
  159.  
  160. void alldone()
  161.    {
  162.    register int t;
  163.  
  164.    if ((g_errenc != 0) && g_dolog && (g_logfp != (FILE *)NULL))
  165.       {        /* errors occurred - copy log file to stderr */
  166.       (void)fflush(g_logfp);        /* make sure file is up-to-date */
  167.       (void)rewind(g_logfp);        /* rewind it */
  168.       while ((t=(int)getc(g_logfp)) != EOF)    /* copy to stderr */
  169.          (void)putc((char)t,stderr);
  170.       (void)fclose(g_logfp);        /* close it */
  171.       g_logfp = (FILE *)NULL;
  172.       }
  173.    abortrun(g_errenc);
  174.    }
  175.  
  176.  
  177. /* This used to be a long in-line macro, but some compilers could not */
  178. /* handle it. */
  179.  
  180. void dbgopen(fp, fname, openmode)
  181. FILE* fp;                /* file pointer */
  182. char* fname;                /* file name */
  183. char* openmode;                /* open mode flags */
  184.    {
  185.    if (DBGOPT(DBG_OKAY_OPEN) && (fp != (FILE *)NULL))
  186.       {
  187.       (void)fprintf(stderr,"%%Open [%s] mode [%s]--[OK]",fname,openmode);
  188.       NEWLINE(stderr);
  189.       }
  190.    if (DBGOPT(DBG_FAIL_OPEN) && (fp == (FILE *)NULL))
  191.       {
  192.       (void)fprintf(stderr,"%%Open [%s] mode [%s]--[FAILED]",fname,openmode);
  193.       NEWLINE(stderr);
  194.       }
  195.    }
  196.  
  197. void devinit(argc, argv)        /* initialize device */
  198. int argc;
  199. char *argv[];
  200.    {
  201.    (void)getbmap();
  202.    if (runlengthcode && !quiet)
  203.       {
  204.       (void)fprintf(stderr, "[Run-length encoding of output file]");
  205.       NEWLINE(stderr);
  206.       }
  207.  
  208.  
  209.    }
  210.  
  211. void devterm()            /* terminate device */
  212.    {
  213.    }
  214.  
  215.  
  216. void fatal(msg)                /* issue a fatal error message */
  217. char *msg;                /* message string */
  218.    {
  219.    if (g_dolog && (g_logfp == (FILE *)NULL) && g_logname[0])
  220.       {
  221.       g_logfp = fopen(g_logname,"w+");
  222.       DEBUG_OPEN(g_logfp,g_logname,"w+");
  223.       if (g_logfp == (FILE *)NULL)
  224.          {
  225.          (void)fprintf(stderr,"Cannot open log file [%s]",g_logname);
  226.          NEWLINE(stderr);
  227.          }
  228.       else
  229.          {
  230.          (void)fprintf(stderr,"[Log file [%s] created]",g_logname);
  231.          NEWLINE(stderr);
  232.  
  233.          }
  234.       }
  235.    if (g_dolog && (g_logfp != (FILE *)NULL) && g_logname[0])
  236.       {
  237.       NEWLINE(g_logfp);
  238.  
  239.       (void)fputs(g_progname,g_logfp);
  240.       (void)fputs(": FATAL--",g_logfp);
  241.       (void)fputs(msg,g_logfp);
  242.       NEWLINE(g_logfp);
  243.       (void)fprintf(g_logfp,"Current TeX page counters: [%s]",tctos());
  244.       NEWLINE(g_logfp);
  245.       }
  246.  
  247.    NEWLINE(stderr);
  248.  
  249.    (void)fputs(g_progname,stderr);
  250.    (void)fputs(": FATAL--",stderr);
  251.    (void)fputs(msg,stderr);
  252.    NEWLINE(stderr);
  253.    (void)fprintf(stderr,"Current TeX page counters: [%s]",tctos());
  254.    NEWLINE(stderr);
  255.    NEWLINE(stderr);
  256.  
  257.    g_errenc = 1;            /* set global fatal exit code */
  258.    alldone();
  259.    }
  260.  
  261. void initglob()            /* initialize global variables */
  262.    {
  263.    register int i;        /* loop index */
  264.    register char* tcp;        /* temporary character pointer */
  265.  
  266.    /***********************************************************************
  267.     Set up masks such that rightones[k]  has 1-bits at the right end  of
  268.     the word from k ..     32-1, where bits are numbered  from
  269.     left (high-order) to right (lower-order), 0 .. 32-1.
  270.  
  271.     img_mask[k] has  a 1-bit  in  position k,  bits numbered  as  above.
  272.     power[k] is  1  <<  k,  and gpower[k]  is  2**k-1  (i.e.  1-bits  in
  273.     low-order k positions).  These 3 require only 32 entries each  since
  274.     they deal with 32-bit words from the PK and GF font files.
  275.  
  276.     These are set  at run-time, rather  than compile time  to avoid  (a)
  277.     problems with C  preprocessors which sometimes  do not handle  large
  278.     constants correctly, and (b) host byte-order dependence.
  279. ***********************************************************************/
  280.  
  281.    rightones[32-1] = 1;
  282.    for (i = 32-2; (i >= 0); --i)
  283.       rightones[i] = (rightones[i+1] << 1) | 1;
  284.  
  285.    img_mask[31] = 1;
  286.    for (i = 30; i >= 0; --i)
  287.       img_mask[i] = img_mask[i+1] << 1;
  288.  
  289.    power[0] = 1;
  290.    for (i = 1; i <= 31; ++i)
  291.       power[i] = power[i-1] << 1;
  292.  
  293.    gpower[0] = 0;        /* NB: we have gpower[0..32], not [0..31] */
  294.    for (i = 1; i <= 32; ++i)
  295.       gpower[i] = power[i-1] | gpower[i-1];
  296.  
  297.    debug_code = 0;
  298.    runmag = STDMAG;            /* default runtime magnification */
  299.  
  300.    npage = 0;
  301.    copies = 1;                /* number of copies of each page */
  302.    topmargin = 1.0;            /* DVI driver standard default */
  303.    leftmargin = 1.0;            /* DVI driver standard default */
  304.  
  305.    subfile[0] = '\0';
  306.  
  307. #if    VIRTUAL_FONTS
  308.    virt_font = FALSE;
  309. #endif
  310.  
  311.    /*
  312.     Copy default file fields into global  variables, then replace by any
  313.     runtime environment  variable definitions.  We need not  do this for
  314.     TOPS-20   and  VAX  VMS,  since   SUBPATH and  FONTPATH are  already
  315.     initialized to logical  names  which   the  operating  system   will
  316.     translate at file open time.
  317.     */
  318.  
  319.    (void)strcpy(helpcmd,"type \\tex\\dvi.hlp");
  320.    (void)strcpy(subpath,"\\TEX\\INPUTS\\");
  321.    (void)strcpy(subname,"TEXFONTS");
  322.    (void)strcpy(subext,".SUB");
  323.    (void)strcpy(fontpath,"\\TEX\\FONTS\\");
  324.    (void)strcpy(fontlist,"PK-GF-PXL");
  325.  
  326.    if ((tcp = getenv("DVIHELP")) != (char *)NULL)
  327.       (void)strcpy(helpcmd,tcp);
  328.  
  329.    if ((tcp = getenv("TEXINPUTS")) != (char *)NULL)
  330.       (void)strcpy(subpath,tcp);
  331.  
  332.    if ((tcp = getenv("TEXFONTS")) != (char *)NULL)
  333.       (void)strcpy(fontpath,tcp);
  334.  
  335.    if ((tcp = getenv("FONTLIST")) != (char *)NULL)
  336.       (void)strcpy(fontlist,tcp);
  337.  
  338.    /* initialize the global vars   -----   why do I have to do this ? */
  339.    g_errenc = 0;        /* has an error been encountered?      */
  340.    g_dolog = TRUE;        /* allow log file creation          */
  341.    g_logfp = (FILE*)NULL;    /* log file pointer (for errors)      */
  342.    plotfp = (FILE*)NULL;    /* plot file pointer              */
  343.    dvifp = (FILE*)NULL;    /* DVI file pointer                */
  344.    hfontptr = (struct font_entry *)NULL;
  345.    runlengthcode = FALSE;        /* this is runtime option '-r' */
  346.    pfontptr = (struct font_entry *)NULL;
  347.    preload = TRUE;        /* preload the font descriptions?        */
  348.    fontfp = (FILE*)NULL;    /* font file pointer                */
  349.    quiet = FALSE;        /* suppress status display when TRUE        */
  350.    backwards = FALSE;    /* print in backwards order            */
  351.    bitmap = (unsigned long int *)NULL;
  352.    }
  353.  
  354.  
  355.  
  356. void option(optstr)            /* process command-line option */
  357. char *optstr;            /* option string (e.g. "-m1500") */
  358.    {
  359.    register unsigned long int k;    /* magnification */
  360.    register int value;        /* converted digit string value */
  361.    register int m;        /* loop index */
  362.    char *p;            /* pointer into optstr */
  363.    int p1,p2,p3;        /* temp values for sscanf() */
  364.    double fltmag;        /* doubleing-point mag value */
  365.  
  366.    typedef struct
  367.       {
  368.       char* envname;
  369.       char* envvar;
  370.       } 
  371.    envstruct;
  372.  
  373.    static envstruct envlist[] =
  374.       {    /* names and addresses of environment vars (alphabetical order) */
  375.       "type \\tex\\dvi.hlp",    helpcmd,
  376.       "PK-GF-PXL",    fontlist,
  377.       "TEXFONTS",    fontpath,
  378.       "TEXINPUTS",    subpath,
  379.       };
  380.  
  381.    if (*optstr != '-')
  382.       return;            /* return if this is not an option */
  383.  
  384.    switch (*(optstr+1))
  385.       {
  386.  
  387.    case 'a':    /* A selects virtual font caching */
  388.    case 'A':
  389. #if    VIRTUAL_FONTS
  390.       virt_font = TRUE;
  391. #endif
  392.       break;
  393.  
  394.    case 'b':    /* b selects backwards printing order */
  395.    case 'B':
  396.       backwards = TRUE;
  397.       break;
  398.  
  399.  
  400.    case 'c':    /* c selects number of copies */
  401.    case 'C':
  402.       copies = (unsigned int) atoi(optstr+2);
  403.       copies = MAX(1,MIN(copies,256)); /* enforce reasonable limits */
  404.       break;
  405.  
  406.  
  407.    case 'd':    /* d selects debug output */
  408.    case 'D':
  409.       debug_code |= (unsigned char)atoi(optstr+2);
  410.       break;
  411.  
  412.  
  413.    case 'e':    /* e specifies ``environment'' variable definition */
  414.    case 'E':    /* We ignore letter case since these come from */
  415.       /* the command line */
  416.       if (!(p = strrchr(optstr,'=')))
  417.          {
  418.          (void)usage(stderr);
  419.          (void)sprintf(message,
  420.          "option():  Bad switch [%s]--expected -eENVNAME=value",
  421.          optstr);
  422.          (void)fatal(message);
  423.          }
  424.       *p = '\0';        /* clobber "=" by string terminator */
  425.       for (m = 0; m < sizeof(envlist)/sizeof(envlist[0]); ++m)
  426.          {
  427.          if (stricmp(optstr+2,envlist[m].envname) == 0)
  428.             {
  429.             (void)strcpy(envlist[m].envvar,p+1);
  430.             return;
  431.             }
  432.          }
  433.       (void)usage(stderr);
  434.  
  435.       (void)sprintf(message,"option():  Bad switch [%s]--expected one of:",
  436.       optstr);
  437.       for (m = 0; m < sizeof(envlist)/sizeof(envlist[0]); ++m)
  438.          {
  439.          (void)strcat(message," ");
  440.          (void)strcat(message,envlist[m].envname);
  441.          }
  442.       (void)fatal(message);
  443.       break;
  444.  
  445.  
  446.    case 'f':    /* f specifies font substitution file */
  447.    case 'F':
  448.       (void)strcpy(subfile,optstr+2);
  449.       break;
  450.  
  451.    case 'l':    /* l prohibits logging of errors */
  452.    case 'L':
  453.       g_dolog = FALSE;
  454.       break;
  455.  
  456.  
  457.    case 'm':    /* m selects alternate magnification */
  458.    case 'M':
  459.       /* Collect 2*value initially.  Then if value is small, assume
  460.     user specified magstep value; magstep k means 1.2**k, where k
  461.     is integral, or half-integral.  Otherwise, assume user has
  462.     specified pxl file magnification (1000 == 200dpi, 1500 ==
  463.     300dpi, etc.).  */
  464.  
  465.  
  466.       if (strchr(optstr+2,'.') != (char *)NULL)
  467.          fltmag = (double)(2.0 * atof(optstr+2));
  468.       else
  469.          fltmag = (double)(2 * atoi(optstr+2));
  470.       if ((0.0 != fltmag) && 
  471.          (-30.0 <= fltmag) && (fltmag <= 30.0)) /* magstep 15 is limit */
  472.          {
  473.          if (fltmag < 0.0)
  474.             runmag = (unsigned long int)(0.5 + 
  475.                (1.0/pow((double)sqrt(1.2),-fltmag))*(double)STDMAG);
  476.          else
  477.             runmag = (unsigned long int)(0.5 + pow((double)sqrt(1.2),fltmag)*
  478.                (double)STDMAG);
  479.          }
  480.       else
  481.          runmag = (unsigned long int)(0.5 + fltmag/2.0);
  482.  
  483.       k = MAGSIZE(actfact(runmag));  /* rounded magnification */
  484.       if (k != runmag)
  485.          {
  486.          (void)sprintf(message,
  487.          "option():  Requested magnification %d not available.",
  488.          (int)runmag);
  489.          (void)warning(message);
  490.          runmag = k;
  491.          k = (unsigned long int) MAX(1,MIN(mag_index,(MAGTABSIZE-1)));
  492.          (void)sprintf(message,
  493.          "  Magnification reset to nearest legal value %d in \
  494. family ..%d..%d..%d..",
  495.          (int)runmag,(int)MAGSIZE(mag_table[k-1]),
  496.          (int)MAGSIZE(mag_table[k]),
  497.          (int)MAGSIZE(mag_table[k+1]));
  498.          (void)warning(message);
  499.          }
  500.       break;
  501.  
  502.  
  503.    case 'o':
  504.    case 'O':    /* o selects output page range (-o# or -o#:# or -o#:#:#) */
  505.       p1 = p2 = p3 = 0;
  506.       value = (int)sscanf(optstr+2,"%d:%d:%d",&p1,&p2,&p3);
  507.       page_begin[npage] = p1;
  508.       page_end[npage] = p2;
  509.       page_step[npage] = p3;
  510.       switch (value)
  511.          {
  512.       case 1:
  513.          optstr++;            /* point past "-" */
  514.  
  515.          do                /* skip over digit string */
  516.             {
  517.             optstr++;
  518.             }
  519.          while (isdigit(*optstr) || (*optstr == '-') || (*optstr == '+'));
  520.  
  521.          if (*optstr)        /* trash follows number */
  522.             {
  523.             (void)usage(stderr);
  524.             (void)sprintf(message,
  525.             "option():  %s is not a legal page number switch",optstr);
  526.             (void)fatal(message);
  527.             }
  528.          else            /* had expected end-of-string */
  529.          page_end[npage] = (int)page_begin[npage];
  530.          page_step[npage] = 1;
  531.          break;
  532.  
  533.       case 2:        /* supply default step */
  534.          page_step[npage] = 1;
  535.          /* FALL THROUGH to case 3 for order check */
  536.  
  537.       case 3:        /* check for positive step */
  538.          page_step[npage] = ABS(page_step[npage]);
  539.          if (page_step[npage] == 0)
  540.             page_step[npage] = 1;
  541.          break;
  542.  
  543.       default:    /* illegal value */
  544.          (void)usage(stderr);
  545.          (void)sprintf(message,
  546.          "option():  %s is not a legal page number switch",optstr);
  547.          (void)fatal(message);
  548.          }
  549.       npage++;
  550.       break;
  551.  
  552.  
  553.    case 'p':    /* p prohibits pre-font loading */
  554.    case 'P':
  555.       preload = FALSE;
  556.       break;
  557.  
  558.  
  559.    case 'q':    /* q inhibits status display */
  560.    case 'Q':
  561.       quiet = TRUE;
  562.       break;
  563.  
  564.  
  565.  
  566.    case 'r':    /* r selects run-length coding of output */
  567.    case 'R':
  568.       runlengthcode = TRUE;
  569.       break;
  570.  
  571.    case 'x':
  572.    case 'X':
  573.       leftmargin = inch(optstr+2);
  574.       break;
  575.  
  576.  
  577.    case 'y':
  578.    case 'Y':
  579.       topmargin = inch(optstr+2);
  580.       break;
  581.  
  582.    default:
  583.       (void)usage(stderr);
  584.       (void)sprintf(message,"option():  %s is not a legal switch", optstr);
  585.       (void)fatal(message);
  586.       }
  587.    }
  588.  
  589.  
  590.  
  591. /* Return index (0,1,...) of substring in string */
  592. /* or -1 if not found.  Letter case is IGNORED. */
  593. int strid2(string,substring)
  594. char string[];     
  595. char substring[];
  596.    {
  597.    register int k;    /* loop index */
  598.    register int limit;    /* loop limit */
  599.    register char *s;
  600.    register char *sub;
  601.  
  602.    limit = (int)strlen(string) - (int)strlen(substring);
  603.  
  604.    for (k = 0; k <= limit; ++k)/* simple (and slow) linear search */
  605.       {
  606.       s = &string[k];
  607.  
  608.       for (sub = &substring[0]; (toupper(*s) == toupper(*sub)) && (*sub); (++s, ++sub))
  609.          /* NO-OP */ ;
  610.  
  611.       if (*sub == '\0')    /* then all characters match */
  612.          return(k);        /* success -- match at index k */
  613.       }
  614.  
  615.    return(-1);            /* failure */
  616.    }
  617.  
  618. /* (trailing zero counters are not printed) */
  619. char * tctos()    /* return pointer to (static) TeX page counter string */
  620.    {    
  621.    register int k;    /* loop index */
  622.    register int n;    /* number of counters to print */
  623.    static char s[111];    /* 10 32-bit counters n.n.n... */
  624.  
  625.    for (n = 9; (n > 0) && (tex_counter[n] == 0); --n)
  626.       /* NO-OP */;
  627.    s[0] = '\0';
  628.    for (k = 0; k <= n; ++k)
  629.       (void)sprintf(strrchr(s,'\0'),"%ld%s",
  630.       tex_counter[k],(k < n) ? "." : "");
  631.    return ((char *)&s[0]);
  632.    }
  633.  
  634.  
  635. void usage(fp)        /* print usage message to fp and return */
  636. FILE *fp;
  637.    {
  638.    (void)fprintf(fp,"[TeX82 DVI Translator Version %s]",VERSION_NO);
  639.    NEWLINE(fp);
  640.    (void)fprintf(fp,"[%s]",DEVICE_ID);
  641.    NEWLINE(fp);
  642.  
  643.    (void)sprintf(message,
  644.    "Usage: %s {-a} {-b} {-c#} {-d#} {-eENVNAME=value} {-ffontsubfile} \
  645. {-l} {-m#} {-o#:#:#} {-o#:#} {-o#} {-p} {-x#{units}} {-y#{units}} dvifile(s)",
  646.    g_progname);
  647.  
  648.    (void)sprintf(message,
  649.    "Usage: %s {-a} {-b} {-c#} {-d#} {-eENVNAME=value} {-ffontsubfile} \
  650. {-l} {-m#} {-o#:#:#} {-o#:#} {-o#} {-p} {-r} {-t} {-x#{units}} {-y#{units}} \
  651. {-z} dvifile(s)",
  652.    g_progname);
  653.    (void)fprintf(fp,message);
  654.    NEWLINE(fp);
  655.  
  656.  
  657.    (void)fprintf(fp,
  658.    "For documentation on this program, try the operating command(s):");
  659.    NEWLINE(fp);
  660.  
  661.    (void)fprintf(fp,helpcmd);
  662.    NEWLINE(fp);
  663.    NEWLINE(fp);
  664.    }
  665.  
  666.  
  667. void warning(msg)                /* issue a warning */
  668. char *msg;                /* message string  */
  669.    {
  670.  
  671.    if (g_dolog && (g_logfp == (FILE *)NULL) && g_logname[0])
  672.       {
  673.       g_logfp = fopen(g_logname,"w+");
  674.       DEBUG_OPEN(g_logfp,g_logname,"w+");
  675.       if (g_logfp != (FILE *)NULL)
  676.          {
  677.          (void)fprintf(stderr,"[Log file [%s] created]",g_logname);
  678.          NEWLINE(stderr);
  679.  
  680.  
  681.          }
  682.       }
  683.  
  684.    if (g_dolog && (g_logfp != (FILE *)NULL) && g_logname[0])
  685.       {
  686.       NEWLINE(g_logfp);
  687.  
  688.       (void)fputs(msg,g_logfp);
  689.       NEWLINE(g_logfp);
  690.       (void)fprintf(g_logfp,"Current TeX page counters: [%s]",tctos());
  691.       NEWLINE(g_logfp);
  692.       }
  693.  
  694.    if (g_dolog && (g_logfp == (FILE *)NULL) && g_logname[0])
  695.       {
  696.       (void)sprintf(message,"Cannot open log file [%s]",g_logname);
  697.       fatal(message);
  698.       }
  699.    NEWLINE(stderr);
  700.  
  701.    (void)fputs(msg,stderr);
  702.    NEWLINE(stderr);
  703.    if (g_logname[0])
  704.       {
  705.       (void)fprintf(stderr,"Current TeX page counters: [%s]",tctos());
  706.       NEWLINE(stderr);
  707.       }
  708.    }
  709.  
  710.  
  711.